#ifndef BONEMANAGER_H
#define BONEMANAGER_H

#include <wx/wx.h>
#include <wx/dcbuffer.h>

#include "../include/Bone.h"
#include "../include/AnimationManager.h"
#include "../include/Config.h"
#include "../include/BoneTreeCtrl.h"

class ProjectFrame;

class BoneManager: public wxPanel
{
    public:
        BoneManager(wxWindow* parent,
                    const wxSize& size,
                    Config* config,
                    BoneTreeCtrl* sceletonTree,
                    wxPanel* informationPanel,
                    wxWindowID id = wxID_ANY,
                    const wxString& name = wxT("Canvas"));
        virtual ~BoneManager();


        /** Sets the root bone if it wasn't setuped before
        * @param Bone* poiter to bone
        * @return Bone* poiter to the root bone
        */
        Bone* setRootBone( Bone* bone );


        /** Tranaslate all bones, by vector specified in point
        * @param translation vector
        */
        void translateSkeletonByVector(wxPoint translation);


        /** Searching bone with specified id
        * @param boneId id of the searched bone
        * @return pointer to the bone, or NULL
        */
        Bone* findBoneById(unsigned boneId) const;

        /** Returns selected bone
        * @return selected bone
        */
        Bone* getSelectedBone() const;

        /** Returns root bone
        * @return root bone
        */
        Bone* getRootBone() const;

        /** Make select on specified bone, and unselect on previous selection
        * @param bone a bone to be selected
        * @param joint a bone's edge number
        */
        void selectBone(Bone* bone, Bone::JOINT joint);

        /** Make hover mark on specified bone
        * @param bone a bone to be hovered
        * @param joint a bone's edge number
        */
        void hoverBone(Bone* bone, Bone::JOINT joint);

        /** Draws all bones
        * @return void
        */
        void draw();

        /** Paints backgound on the given wxDC. Called by the draw methot automatically
        * @param dc - any of wxDC-based dc
        */
        void PaintBackground(wxDC& dc);

        /** Set all bones to states specified in member bonesStates */
        void applySkeletonState(unsigned frameNumber);

        /** Updaten info panel with selecte bone properites */
        void updateBoneInfo() const;

        /** Rebilds skeleton tree */
        void rebildSkeletonTree() const;

        /** Get bones states from current sceleton position
        *   and put it into member bonesStates
        *   @param createNew when true new vector of bonesStates is created,
        *   when false current bonesStates us Updating
        *   @return member bonesStates
        */
        std::vector<BoneState*>* saveSkeletonState(bool createNew);

        /** Returns vector of skeleton states
        * @return skeleton State (bonesStaes)
        */
        std::vector<BoneState*>* getBonesStates();

        /** Save skeleton to xml file
        * @param fileName name of the file
        * @param withAnimation - saving together with animation
        */
        void saveSkeletonToFile(const wxString& fileName, bool withAnimation);

        /** Load skeleton from xml file
        * @param fileName name of the file
        * @param withAnimation - loading from file together with animation
        */
        void loadSkeletonFromFile(const wxString& fileName, bool withAnimation);

        /** For all bone set its current absolute angle to its orinalAngle, which is used to restore from states*/
        //void setBonesOrginalAngles();

        /** Return pointer to animation manager
        * @return pointer to animation manager
        */
        AnimationManager* getAnimationManager() const;

        ProjectFrame* getProjectFrame() const;

    private:

        /** Method connected to the EVT_PAINT
        * @param evt - wxPaintEvent holding event's detailed data
        */
        void paintEvent(wxPaintEvent & evt);


        /** Method connected to the EVT_ERASE_BACKGROUND
        * @param evt - wxEraseEvent holding event's detailed data
        */
        void eraseBackground(wxEraseEvent& evt);

        /** Method connected to the EVT_MOTION
        * @param evt - wxMouseEvent holding event's detailed data
        */
        void mouseMoved(wxMouseEvent& event);


        void onKeyDown(wxKeyEvent& e);

        /** Method connected to the EVT_LEFT_DOWN
        * @param evt - wxMouseEvent holding event's detailed data
        */
        void mouseDown(wxMouseEvent& event);

        /** Method connected to the EVT_LEFT_UP
        * @param evt - wxMouseEvent holding event's detailed data
        */
        void mouseReleased(wxMouseEvent& event);

        /** Sceleton's root bone */
        Bone* rootBone;

        /** The last selected bone */
        Bone* selected;

        /** Hovered bone */
        Bone* hovered;

        /** Keeps info if it's draggig or not */
        bool dragging;

        /** Kepps infor if user is draging around to create a new bone */
        bool creatingBone;

        /** Current bones states */
        std::vector<BoneState*> *bonesStates;

        /** Bones staes used only to showing, not stored in Animation Manager */
        std::vector<BoneState*> *tmpBonesStates;


        /** Config file pointer*/
        Config* config;

        /** AnimationManager pointer*/
        AnimationManager* animManager;

        /** Tree bones */
        BoneTreeCtrl *skeletonTree;

        /** Panel with bone's properties */
        wxPanel* informationPanel;

        /** Main Frame */
        ProjectFrame* projectFrame;

    DECLARE_EVENT_TABLE()
};

#endif // BONEMANAGER_H
